package com.yang.service;

import com.alibaba.fastjson.JSON;
import com.yang.config.ElasticsearchConfig;
import com.yang.pojo.Content;
import com.yang.utils.HtmlParseUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author shiwen
 * @date 2021/4/28
 */
@Service
public class ContentService {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private HtmlParseUtils htmlParseUtils;

    public Boolean searchKey(String keyword) throws IOException {
        BulkRequest request = new BulkRequest();
        request.timeout(TimeValue.timeValueMinutes(3));
        List<Content> contentList = htmlParseUtils.searchBykey(keyword);
        for (Content content : contentList) {
            System.out.println(JSON.toJSONString(content));
            request.add(new IndexRequest("jd_goodslist").source(JSON.toJSONString(content), XContentType.JSON));
        }
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        if (response.hasFailures()) {
            System.out.println("================" + response.buildFailureMessage());
        }
        return !response.hasFailures();
    }

    public List<Content> getSearchList(String keyword) throws IOException {
        SearchRequest request = new SearchRequest("jd_goodslist");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", "java");
        searchSourceBuilder.query(matchQueryBuilder);
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(20);
        request.source(searchSourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        List<Content> contentList = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            Content content = JSON.parseObject(hit.getSourceAsString(), Content.class);
            contentList.add(content);
        }
        return contentList;
    }

    // 搜索高亮
    public List<Map<String, Object>> searchHighLight(String keyword, int pageNo, int pageSize) throws IOException {
        SearchRequest request = new SearchRequest("jd_goodslist");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("title", keyword);

        // 分页
        searchSourceBuilder.from(pageNo);
        searchSourceBuilder.size(pageSize);

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        // 配置多个高亮
        highlightBuilder.requireFieldMatch(true);
        // 查询
        searchSourceBuilder.highlighter(highlightBuilder);
        searchSourceBuilder.query(matchQueryBuilder);
        // 请求查询
        request.source(searchSourceBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, HighlightField> fields = hit.getHighlightFields();
            HighlightField title = fields.get("title");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            // 解析高亮字段
            if (title != null) {
                Text[] fragments = title.getFragments();
                String name = "";
                // 这里无非就是将hit里面的普通字段替换成高亮的字段
                for (Text text : fragments) {
                    name += text;
                }
                System.out.println("name = " + name);
                // 替换成高亮内容
                sourceAsMap.put("title", name);
            }
            resultList.add(sourceAsMap);
        }
        return resultList;
    }

}